#ifndef TILE_H
#define TILE_H

/*!
 * \file tile.h
 * \brief Header of class CTile
 * \author Benjamin Toueg
 * \version 0.1
 */

#include "object3d.h"
#include "tilebehaviour.h"

#include <SFML/Graphics.hpp>

#include <assert.h>
#include <map>

class CTileBehaviour;

/*! \class CTile
* \brief Elemental structure of a level
*
*  The tile is a box. The top has different texture corresponding on the membe m_uiTimesVisited
*/
class CTile: public CObject3D
{
public:
    /*! \brief Default constructor */
    CTile():m_uiTimesVisited(0), m_uiMaxVisited(1),m_pBehaviour(NULL) { createDisplayList(); }
    /*! \brief Custom constructor */
    CTile(const int& z, const int& xy, const unsigned int& n, const CTileBehaviour::eBehaviour& b = CTileBehaviour::STRAIGHT); //inline
    /*! \brief Copy constructor */
    CTile(const CTile& copy); // inline
    /*! \brief Destructor */
    ~CTile();
    void                    draw(std::map<int,sf::Image>* map_texture_boxes, std::map<std::pair<int,int>,sf::Image>* map_texture_tiles);
    const unsigned int&     getNbVisites() const { return m_uiTimesVisited; };
    const unsigned int&     getNbVisitesMax() const { return m_uiMaxVisited; };
    CTile*                  giveThisAsOwnTile(Vector3d vec);
    CTile*                  giveThisAsTileToChange(const Vector3d& vec);
    void                    incrVisites() { m_uiTimesVisited=(++m_uiTimesVisited)%m_uiMaxVisited; };
    bool                    isFinished() const { return (m_uiTimesVisited == m_uiMaxVisited - 1); };
    void                    setCTile(const int& z, const int& xy, const unsigned int& n) { setCurrentPos(z,xy); m_uiMaxVisited = n+1; };

private:
    void                    createDisplayList();
    void                    deleteDisplayList();
    GLuint m_uiDisplayList;
    unsigned int m_uiTimesVisited; /*!< number of times it has been visited*/
    unsigned int m_uiMaxVisited; /*!< number of visit to reach*/
    CTileBehaviour* m_pBehaviour; /*!< interface for the behavior o of the tile, i.e. when it considers it has been visited*/
};

inline CTile::CTile(const int& z, const int& xy, const unsigned int& n, const CTileBehaviour::eBehaviour& b):m_uiTimesVisited(0),m_uiMaxVisited(n+1)
{
    setCurrentPos(z,xy);
    switch ( b )
    {
    case CTileBehaviour::STRAIGHT:
        m_pBehaviour = new CTileStraightBehaviour;
    break;
    case CTileBehaviour::WEIRD:
        m_pBehaviour = new CTileWeirdBehaviour;
    break;
    default:
        assert(false&&"Error in CTile regular constructor");
    break;
    }
    createDisplayList();
}

inline CTile::CTile(const CTile& copy):CObject3D(copy),m_uiTimesVisited(copy.m_uiTimesVisited),m_uiMaxVisited(copy.m_uiMaxVisited)
{
    assert(copy.m_pBehaviour!=NULL&&"Error in CTile copy constructor");
    switch ( copy.m_pBehaviour->myBehaviour() )
    {
    case CTileBehaviour::STRAIGHT:
        m_pBehaviour = new CTileStraightBehaviour;
    break;
    case CTileBehaviour::WEIRD:
        m_pBehaviour = new CTileWeirdBehaviour;
    break;
    default:
        assert(false&&"Error in CTile copy constructor");
    break;
    }
    createDisplayList();
}
#endif //TILE_H
